package at.ac.tuwien.big.forms.htmlgen

import at.ac.tuwien.big.forms.AttributePageElement
import at.ac.tuwien.big.forms.DateSelectionField
import at.ac.tuwien.big.forms.Form
import at.ac.tuwien.big.forms.FormModel
import at.ac.tuwien.big.forms.Page
import at.ac.tuwien.big.forms.PageElement
import at.ac.tuwien.big.forms.RelationshipPageElement
import at.ac.tuwien.big.forms.SelectionField
import at.ac.tuwien.big.forms.TextArea
import at.ac.tuwien.big.forms.TextField
import at.ac.tuwien.big.forms.TimeSelectionField
import java.io.File
import java.util.List
import org.eclipse.emf.common.util.EList
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.generator.IGenerator
import at.ac.tuwien.big.forms.AttributeType
import at.ac.tuwien.big.forms.Literal
import at.ac.tuwien.big.forms.Column
import at.ac.tuwien.big.forms.Table
import at.ac.tuwien.big.forms.Condition
import at.ac.tuwien.big.forms.CompositeCondition
import at.ac.tuwien.big.forms.AttributeValueCondition

class Form2HTMLGenerator implements IGenerator {

  override doGenerate(Resource resource, IFileSystemAccess fsa) {
    
    val listOfModels = resource.resourceSet.resources
    var formModel = null as FormModel
    for(model : listOfModels){
      if(model.contents.get(0) instanceof FormModel)
        formModel = model.contents.get(0) as FormModel
    }
    val name = new File('output.html');

    fsa.generateFile(
      name.toString,
      '''<!DOCTYPE html>
        <html lang="en">
        «generateHead(formModel)»
          <body>
          
    «FOR Form f : formModel.forms»
      <div class="form" id="«f.name»">
        <form action="#" class="register">
          <h1>«f.title»</h1>
          <h2>«f.description»</h2>
          «generatePages(f.pages)»
        </form>
      </div>
    «ENDFOR»
     
    </body>
        </html>'''  
    )
  }
  
  def generatePages(List<Page> pages) '''
    «FOR Page p : pages»
      <div class="page" id="«p.title»">
        <fieldset class="row1">
        <h3>«p.title»</h3>
        «generatePageElements(p.pageElements)»
        </fieldset>
      </div>
    «ENDFOR»
  '''
  

  def generatePageElements(EList<PageElement> list) 
  	'''
	«FOR PageElement pe :list»
      «IF pe instanceof AttributePageElement»
        «generatePageElement(pe)»
      «ENDIF»
      «IF pe instanceof RelationshipPageElement»
       	«generatePageElement(pe)» 
      «ENDIF»
	«ENDFOR»
    '''

  
	  def dispatch generatePageElement(AttributePageElement element) 
	  	'''
	    «IF element instanceof TextField»
	      «generateAttributePageElement(element)»
	      «ENDIF»
	    «IF element instanceof DateSelectionField»
	      «generateAttributePageElement(element)»
	      «ENDIF»
	    «IF element instanceof TimeSelectionField»
	      «generateAttributePageElement(element)»
	      «ENDIF»
	    «IF element instanceof TextArea»
	      «generateAttributePageElement(element)»
	      «ENDIF»
	    «IF element instanceof SelectionField»
	      «generateAttributePageElement(element)»
	      «ENDIF»
		'''
  
	  def generateAttributePageElement(TextField element) 
		'''
			<p>
			<label for="«element.elementID»">«element.label»«IF element.attribute.mandatory»«generateMandatoryStar()»«ENDIF»</label>
			<input type="text" id="«element.elementID»" «IF element.attribute.mandatory» «generateMandatoryClass()» «ENDIF»/>
			</p>
		'''
	  
	
	def generateMandatoryClass() 
		'''
		class="mandatory"
		'''
	
	
	def generateMandatoryStar() 
		'''
		<span>*</span>
		'''
  
  def generateAttributePageElement(DateSelectionField element) 
    '''
	<p>
	<label for="«element.elementID»">«element.attribute.name»</label>
	<input type="date" id="«element.elementID»"/>
	</p>
    '''
  
  
  def generateAttributePageElement(TimeSelectionField element) 
    '''
	<p>
	<label for="«element.elementID»">«element.attribute.name»</label>
	<input type="time" id="«element.elementID»"/>
	</p>
    '''
  
  
  def generateAttributePageElement(TextArea element) 
    	'''
			<p>
			<label for="«element.elementID»">«element.label» «IF element.attribute.mandatory» «generateMandatoryStar()»«ENDIF»</label>
			<textarea id="«element.elementID»" «IF element.attribute.mandatory» «generateMandatoryClass()» «ENDIF»></textarea>
			</p>
    	'''
  
  
  def generateAttributePageElement(SelectionField element) 
    	'''
			<p>
			<label for="«element.elementID»">«element.label» «IF element.attribute.mandatory» «generateMandatoryStar()»«ENDIF»</label>
			<select id="«element.elementID»" name="«element.attribute.name»" «IF element.attribute.mandatory» «generateMandatoryClass()» «ENDIF»/>
			<option value="default"> </option>
			«IF element.attribute.type == AttributeType.NONE»
				«FOR Literal l : element.attribute.enumeration.literals»
					«generateLiteral(l)»
				«ENDFOR»
			«ENDIF»
			«IF element.attribute.type == AttributeType.BOOLEAN»
				«generateLiteralBoolean()»
			«ENDIF»
			</p>
    	'''
  
	
	def generateLiteralBoolean() 
		'''
		<option value="«true»">yes</option>
		<option value="«false»">no</option>
		'''
	
	
	def generateLiteral(Literal literal) 
		'''
		<option value="«literal.name»">«literal.value»</option>
		'''
	
  
	def generateAttributePageElement(Column column) 
    	'''
		<th>«column.attribute.name»</th>
    	'''
	
   
  def dispatch generatePageElement(RelationshipPageElement element) 
'''
  	«IF element instanceof at.ac.tuwien.big.forms.List»
  		«generateList(element)»
  	«ENDIF»
  	«IF element instanceof at.ac.tuwien.big.forms.Table»
  		«generateTable(element)»
  	«ENDIF»
  '''
  
	
	def generateTable(at.ac.tuwien.big.forms.Table element) 
	'''
	<div class="table" id="«element.elementID»">
		<fieldset class="row1">
		<legend class="legend">«element.label»</legend>
			<table>
				<tr id=«element.elementID»_header>
					«FOR co : element.columns»
						«generateAttributePageElement(co)»
					«ENDFOR»
				</tr>
			</table>
		</fieldset>
	</div>
	'''
	
	
	def generateList(at.ac.tuwien.big.forms.List list) 
	'''
		<div class="list" id="«list.elementID»">
			<fieldset class="row1">
				<legend class="legend">«list.label»</legend>
				<ul></ul>
			</fieldset>
		</div>
	'''
	
      
  def generateHead(FormModel formModel) 
    '''<head>
        <title>Form</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
        <link rel="stylesheet" type="text/css" href="../assets/form.css"/>
        <script src="../assets/jquery-1.10.2.min.js" type="text/javascript"></script>
        <script src="../assets/form.js" type="text/javascript"></script>
        <script type="text/javascript">
        $(document).ready(
        function(){         
					«FOR f : formModel.forms»
						«IF f.welcomeForm»
							form.addWelcomeForm('«f.title»');
						«ENDIF»
					«ENDFOR»

					«FOR f : formModel.forms»
						«FOR p : f.pages»
							«FOR pe : p.pageElements»
								«IF pe instanceof at.ac.tuwien.big.forms.TextField»
									«IF pe.format != null»
										form.addRegularExpression('«pe.elementID»', '«pe.format»');
									«ENDIF»
								«ENDIF»
							«ENDFOR»
						«ENDFOR»
					«ENDFOR»
					
					«FOR f : formModel.forms»
						«FOR p : f.pages»
							«FOR pe : p.pageElements»
								«IF pe instanceof at.ac.tuwien.big.forms.Table»
									form.addRelationshipPageElement ('«p.title»', '«pe.elementID»', '«pe.editingForm.title»', 'table', '«pe.relationship.lowerBound»', '«pe.relationship.upperBound»');
								«ENDIF»
								«IF pe instanceof at.ac.tuwien.big.forms.List»
									form.addRelationshipPageElement ('«p.title»', '«pe.elementID»', '«pe.editingForm.title»', 'list', '«pe.relationship.lowerBound»', '«pe.relationship.upperBound»');
								«ENDIF»
							«ENDFOR»
						«ENDFOR»
					«ENDFOR»
					
									
					«FOR f : formModel.forms»
						«FOR p : f.pages»
							«IF p.condition != null»
									«registerCondition(p, null, p.condition, true)»
							«ENDIF»
							«FOR pe : p.pageElements»
								«IF pe.condition != null»
									«registerCondition(p, pe, pe.condition, false)»
								«ENDIF»
							«ENDFOR»
						«ENDFOR»
					«ENDFOR»
        form.init();
        });
        </script>
      </head>'''
	
	def registerCondition(Page p, PageElement pe, Condition condition, boolean page) '''
		«IF condition instanceof CompositeCondition»
			«registerCompositeCondition(p, pe, condition, page)»
		«ENDIF»
		
		«IF condition instanceof AttributeValueCondition»
			«registerAttributeValueCondition(p, pe, condition, page)»
		«ENDIF»
		
	'''
	


	def registerAttributeValueCondition(Page p, PageElement pe, AttributeValueCondition condition, boolean page) '''
	form.addAttributeValueCondition('«condition.conditionID»','null','«IF page»«p.title»«ENDIF»«IF !page»«pe.elementID»«ENDIF»','«condition.value»', '«condition.type»');
	'''
	
	def registerCompositeCondition(Page p, PageElement pe, CompositeCondition condition, boolean page) '''
		form.addCompositeCondition('«condition.conditionID»','null','«condition.compositionType»');
«««		«FOR Condition cond: condition.composedConditions»
«««		«registerCondition(p, pe, Condition cond, page)»
«««		«ENDFOR»
'''
  
}